/**
 * GitCode API general request wrapper.
 */

import { fetch, type RequestInit, type HeadersInit } from "undici";

export interface GitCodeRequestInput {
  baseUrl?: string;
  token: string;
  method: string;
  path: string;
  query?: Record<string, any>;
  body?: Record<string, any>;
  headers?: Record<string, string>;
}

function buildUrl(baseUrl: string, path: string, query?: Record<string, any>): URL {
  const url = new URL(path, baseUrl);
  if (query) {
    for (const [key, value] of Object.entries(query)) {
      if (value !== undefined && value !== null) {
        url.searchParams.set(key, String(value));
      }
    }
  }
  return url;
}

export async function gitcodeRequest(input: GitCodeRequestInput) {
  // Use default GitCode API v5 if baseUrl is not provided
  const baseUrl = input.baseUrl || 'https://gitcode.com/api/v5';
  const url = buildUrl(baseUrl, input.path, input.query);

  console.log(`[GitCode] Requesting: ${input.method} ${url}`);

  const headers: HeadersInit = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "Authorization": input.token.startsWith("Bearer ") ? input.token : `Bearer ${input.token}`,
    ...input.headers,
  };

  const options: RequestInit = {
    method: input.method,
    headers,
  };

  if (input.body && Object.keys(input.body).length > 0) {
    options.body = JSON.stringify(input.body);
  }

  try {
    const response = await fetch(url.href, options);
    const responseText = await response.text();

    let data: any;
    try {
      data = JSON.parse(responseText);
    } catch {
      data = { raw: responseText };
    }

    if (!response.ok) {
      console.error(`[GitCode] API Error: ${response.status}`, data);
    }

    return {
      status: response.status,
      ok: response.ok,
      url: url.href,
      data,
    };
  } catch (error) {
    console.error(`[GitCode] Network or fetch error for ${url.href}:`, error);
    throw error; // Re-throw to be caught by the tool handler
  }
}